iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
2
Software Development

保持前進、持續優化程式碼內涵系列 第 4

04. 攻城獅最討厭的、但又必需作的事情~命名規則

  • 分享至 

  • xImage
  •  

各位看倌還記得02. 看的懂的程式碼,才是好的程式碼看到的程式嗎?

造成程式碼不易閱讀的因素有很多,但最常見的就是命名行為不確實。下面,我們將前文出現的程式碼,擷取一小段落於下方,讓我們來 code review 有那些問題是因為命名行為不確實造成的。

Code review

    int[,] k111 = k;
    Random innerRnd8 = new Random(Guid.NewGuid().GetHashCode());
    int a1 = innerRnd8.Next(ggg);
    Random innerRnd9 = new Random(Guid.NewGuid().GetHashCode());
    int a2 = innerRnd9.Next(ggg);

    double rrr = _RRR(k[0, a1], k[1, a1], im_1, im2_1);
    double rrr_1 = _RRR(k[0, a2], k[1, a2], im_1, im2_1);

接著將上面程式碼,所使用的函數 _RRR(...) 的宣告也找出來。

int _RRR(int _X, int _Y, int[, ,] im_1, int[, ,] im2_1)
{
	... 
}

1. 不具代表性的變數名稱

    int[,] k111 = k;

在看到變數 k 的當下,很難知道它所代表意思。所以只好再回頭查看 k 這個物件,它儲存了什麼資訊、它有什麼用途。

花費在查詢無意義命名的變數的用途與資訊的時間,就是變向的浪費寶貴的開發時間。

    Random innerRnd8 = new Random(Guid.NewGuid().GetHashCode());
    int a1 = innerRnd8.Next(ggg);
    Random innerRnd9 = new Random(Guid.NewGuid().GetHashCode());
    int a2 = innerRnd9.Next(ggg);

    double rrr = _RRR(k[0, a1], k[1, a1], im_1, im2_1);

接著,我們從程式碼中,可以得知 a1, a2 儲存的內容是一組亂數資料,這樣的寫法很正常。
但配合變數 k 使用時,在閱讀性上並沒有那麼直覺。

所有的變數名稱,識別性太低,而且無法明確的表示該變數的意義。

另外,ggg 其實是類別的成員,在本來的程式碼中,無法直接辨識變數的屬於區域變數、或是類別成員。

若是類別成員與區域變數無法區分,可能會導致開發時,非預期的 BUG。

2. 難以判讀的函數名稱

    double rrr = _RRR(k[0, a1], k[1, a1], im_1, im2_1);
    double rrr_1 = _RRR(k[0, a2], k[1, a2], im_1, im2_1);

變數 rrr 代表的意思?函數 _RRR(...) 的功能為何?

不明確的函數名稱,會導致無法從函數名稱直接得知回傳物件的意義。

3. 不具代表性的函數參數名稱

int _RRR(int _X, int _Y, int[, ,] im_1, int[, ,] im2_1)
{
	... 
}

其實這跟第一點是相同的,無法直接經由參數的名稱,進一步瞭解到參數的意義,可能會造成需要額外的說明文件或註解。

優化方向

1. 使用有代表性意義的變數名稱

當我們review 完這段程式碼後,發現 k 是一組長度為 ggg 的二維陣列,實際上它的用途是儲存基因演算法中,所使用的樣本資料。ggg 代表的取樣的數量。

private int ggg = 40;
    
public int[,] ga(int[,,] im_1, int[,,] im2_1)
{
    int[,] k = new int[2, ggg];
    ...
}

若是將上方的程式碼改為下面的寫法。

private int _sampleAmount = 40;
    
public int[,] ga(int[,,] im_1, int[,,] im2_1)
{
    int[,] sampleGroup = new int[2, _sampleCount];
    ...
}

這樣的閱讀性是是不是高了一點。

2. 可描述功能的函數名稱

函數 _RRR(...) 的功能,主要是為了找出兩張影像在特定座標位置的誤差量。但是在原本的函數名稱中,很難去表示出該函數的功能目標。

int _RRR(int _X, int _Y, int[, ,] im_1, int[, ,] im2_1)
{
	... 
}

若是將上方的程式碼改為下面的寫法。

int CalcImageOverlapError(int x, int y, int[, ,] image1, int[, ,] image2)
{
	... 
}

使用 CalcImgeOverlapError 是否更能快速了解函數的功能與目標。

補充

其實,上面將變數名稱、函數名稱更改為有意義名稱的動作,就是重構的一種行為。

重點滙整

  • 函數名稱應該與動作行為相符。
  • 變數名稱應該具有識別性與描述性。

上一篇
03. 工欲善其事、必先利其器 !英雄王,武器的儲備足夠嗎?
下一篇
05. 隱藏在原始碼的小幫手~註解
系列文
保持前進、持續優化程式碼內涵24
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言